/*
 * @Author: zhouwei wei.zhou@flip.fun
 * @Date: 2024-04-02 20:43:46
 * @LastEditors: zhouwei wei.zhou@flip.fun
 * @LastEditTime: 2024-04-07 17:53:49
 * @FilePath: /50/手撕系列/promise.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
/**
 *
 *
 */
class MyPromise {
	RESOLVED = 'resolved'
	PENGING = 'penging'
	REJECTED = 'rejected'
	state = this.PENGING
	value = ''
	resolveQueue = []
	rejectQueue = []
	constructor(callback) {
		try {
			callback(this.resolve, this.reject)
		} catch (error) {
			this.reject(error)
		}
	}

	resolve(value) {
		/**
		 * 根据promise的特性,以下为注意点
		 *  1.如果resolve是一个promise,则需要等待该promise的状态发生改变
		 * 	2.状态一旦发生改变,不可更改
		 *
		 */
		if (value instanceof MyPromise) {
			return value.then(this.resolve, this.reject)
		}
		if (this.state === this.PENGING) {
			this.value = value
			this.state = this.RESOLVED
		}
		setTimeout(() => {
			this.resolveQueue.forEach(resolveCallback => resolveCallback(value))
		}, 0)
	}

	reject(value) {
		if (this.state === this.PENGING) {
			this.value = value
			this.state = this.REJECTED
		}
		setTimeout(() => {
			this.rejectQueue.forEach(rejectCallback => rejectCallback(value))
		}, 0)
	}
	then(resolveCallback, rejectCallback) {
		if (typeof resolveCallback === 'function') {
			if (this.state === this.PENGING) {
				this.resolveQueue.push(resolveCallback)
			}
			if (this.state === this.RESOLVED) {
				resolveCallback.call(this, this.value)
			}
		}
		if (typeof rejectCallback === 'function') {
			if (this.state === this.PENGING) {
				this.resolveQueue.push(rejectCallback)
			}
			if (this.state === this.RESOLVED) {
				rejectCallback.call(this, this.value)
			}
		}
	}
	catch(rejectCallback) {
		if (typeof rejectCallback === 'function') {
			if (this.state === this.PENGING) {
				this.rejectQueue.push(rejectCallback)
			}
			if (this.state === this.REJECTED) {
				rejectCallback.call(this, this.value)
			}
		}
	}
}

new MyPromise((resolve, reject) => {
	setTimeout(() => {
		resolve(1)
	}, 3000)
})
	.then(value => {
		console.log(value)
	})
